
import { init } from "snabbdom/build/package/init";
import { h } from "snabbdom/build/package/h";

import { styleModule } from "snabbdom/build/package/modules/style";
import { eventListenersModule } from "snabbdom/build/package/modules/eventlisteners";
import { propsModule } from "snabbdom/build/package/modules/props";
import { classModule } from "snabbdom/build/package/modules/class";

const patch = init([
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
]);

let vnode;
let nextKey = 4;
const margin = 8;
let sortBy = "title";
let totalHeight = 0;
const originalData = [
  {
    rank: 1,
    title: "复仇者联盟",
    desc: "复仇者联盟",
    elmHeight: 0,
  },
  {
    rank: 2,
    title: "蜘蛛侠",
    desc: "蜘蛛侠",
    elmHeight: 0,
  },
  {
    rank: 3,
    title: "奇异博士",
    desc: "奇异博士",
    elmHeight: 0,
  },
];
let data = [
  originalData[0],
  originalData[1],
  originalData[2],
];


// 排序按钮事件
function changeSort(prop) {
  sortBy = prop;
  data.sort((a, b) => {
    if (a[prop] > b[prop]) {
      return 1;
    }
    if (a[prop] < b[prop]) {
      return -1;
    }
    return 0;
  });
  render();
}

// 新增按钮事件
function add() {
  const n = originalData[Math.floor(Math.random() * 3)];
  data = [
    { rank: nextKey++, title: n.title, desc: n.desc, elmHeight: 0 },
  ].concat(data);
  // 调用两次render 是为了防止高度异常
  render();
  render();
}

// 删除事件
function remove(movie) {
  data = data.filter((m) => {
    return m !== movie;
  });
  render();
}

// 一行展示的数据
function movieView(movie) {
  return h(
    "div.row",
    {
      key: movie.rank,
      style: {
        opacity: "0",
        transform: "translate(-200px)",
        delayed: { transform: `translateY(${movie.offset}px)`, opacity: "1" },
        remove: {
          opacity: "0",
          transform: `translateY(${movie.offset}px) translateX(200px)`,
        },
      },
      // 注册钩子函数
      hook: {
        // dom节点操作完成后，获取dom的真实高度
        insert: (vnode) => {
          movie.elmHeight = vnode.elm.offsetHeight;
        },
      },
    },
    [
      h("div", { style: { fontWeight: "bold" } }, movie.rank),
      h("div", movie.title),
      h("div", movie.desc),
      h(
        "div.btn.rm-btn",
        {
          on: {
            click: () => {
              remove(movie);
            },
          },
        },
        "x"
      ),
    ]
  );
}

// 根据data中的数据，重新渲染
function render() {
  data = data.reduce((acc, m) => {
    const last = acc[acc.length - 1];
    m.offset = last ? last.offset + last.elmHeight + margin : margin;
    return acc.concat(m);
  }, []);
  // 列表的整体高度
  totalHeight =
    data.length === 0
      ? 0
      : data[data.length - 1].offset + data[data.length - 1].elmHeight;
  // 将新的vnode保存起来，作为下次的旧vnode
  vnode = patch(vnode, view(data));
}

// 页面vnode生成
function view(data) {
  return h("div", [
    h("h1", "Top 10 movies"),
    h("div", [
      h("a.btn.add", { on: { click: add } }, "Add"),
      "Sort by: ",
      h("span.btn-group", [
        h(
          "a.btn.rank",
          {
            class: { active: sortBy === "rank" },
            on: {
              click: () => {
                changeSort("rank");
              },
            },
          },
          "Rank"
        ),
        h(
          "a.btn.title",
          {
            class: { active: sortBy === "title" },
            on: {
              click: () => {
                changeSort("title");
              },
            },
          },
          "Title"
        ),
        h(
          "a.btn.desc",
          {
            class: { active: sortBy === "desc" },
            on: {
              click: () => {
                changeSort("desc");
              },
            },
          },
          "Description"
        ),
      ]),
    ]),
    h(
      "div.list",
      { style: { height: totalHeight + "px" } },
      // 每一行子元素
      data.map(movieView)
    ),
  ]);
}

window.addEventListener("DOMContentLoaded", () => {
  const container = document.getElementById("container");
  vnode = patch(container, view(data));
  render();
});